package WWTPAgent;

import jade.content.ContentElement;
import jade.content.ContentManager;
import jade.content.onto.basic.Action;
import jade.core.AID;
import jade.core.behaviours.CyclicBehaviour;
import jade.domain.FIPANames;
import jade.lang.acl.ACLMessage;
import jade.lang.acl.MessageTemplate;
import jade.proto.SimpleAchieveREInitiator;
import wwtp.ontology.DirectSendWater;
import wwtp.ontology.Laminate;
import wwtp.ontology.Origin;
import wwtp.ontology.RequestHelp;
import wwtp.ontology.SendWater;
import wwtp.ontology.Time;
import wwtp.ontology.Volume;
import wwtp.ontology.VolumeOf;
import wwtp.ontology.Water;
import DataBases.ToxicNotificationObject;

public class WaterAnalysisBehaviour extends CyclicBehaviour {

	protected MessageTemplate mt;
	protected ContentManager manager;

	@Override
	public void action() {
		// TODO Auto-generated method stub
		mt = MessageTemplate.or(

				MessageTemplate.and(MessageTemplate
				.MatchConversationId("ControlFlowProtocol"), MessageTemplate
				.MatchPerformative(ACLMessage.INFORM)),

				MessageTemplate.and(MessageTemplate
				.MatchConversationId("LaminateProtocol"), MessageTemplate
				.MatchPerformative(ACLMessage.INFORM)));


		manager = myAgent.getContentManager();
		final ACLMessage msg = myAgent.receive(mt);
		if (msg != null) {
			try {

				ContentElement ce = manager.extractContent(msg);

				ACLMessage request = new ACLMessage(ACLMessage.REQUEST);
				request.setProtocol(FIPANames.InteractionProtocol.FIPA_REQUEST);
				request.setLanguage(((WWTPAgent) myAgent).codec.getName());
				request.setOntology(((WWTPAgent) myAgent).ontology.getName());
				request.addReceiver(msg.getSender());

				Action actionOp = null;

				/*
				 * LAMINATE PROTOCOL
				 */
				if (msg.getConversationId().compareTo("LaminateProtocol") == 0){

					request.setConversationId("LaminateProtocol-action");
					VolumeOf vof = (VolumeOf)ce;
					Volume v = new Volume();

					if (vof.getVolume().getLitres() < ((WWTPAgent)myAgent).maxCapacity - ((WWTPAgent)myAgent).usedCapacity){
						v.setLitres(vof.getVolume().getLitres());
					}
					else
					{
						v.setLitres((float) (((WWTPAgent)myAgent).maxCapacity - ((WWTPAgent)myAgent).usedCapacity));
					}
					
					//v.setLitres(0);

					Laminate lam = new Laminate();
					lam.setVolume(v);
					actionOp = new Action(msg.getSender(), lam);

					//Send Action
					manager.fillContent(request, actionOp);
					myAgent.addBehaviour(new SimpleAchieveREInitiator(myAgent, request) {

						@Override
						protected ACLMessage prepareRequest(ACLMessage arg0) {
							// TODO Auto-generated method stub
							return super.prepareRequest(arg0);
						}

					});

				}
				/*
				 * CONTROLFLOW PROTOCOL
				 */
				else{
					//Test: RequestForHelp cuando Non-notified toxic effluent detected
					boolean requestForHelp = false;

					request.setConversationId("ControlFlowProtocol-action");

					// Analize water
					SendWater sw = (SendWater)ce;
					Water water = sw.getWater();

					//detectar si es notificado o no si viene de un sewer y no de un tank por bypass
					if (sw.getOrigin().getName().contains("Sewer")){
						ToxicNotificationObject notification = new ToxicNotificationObject(sw.getHour().getHours(),
																					sw.getHour().getMinutes(),
																					sw.getHour().getSeconds(),
																					sw.getOrigin().getName());

						if (((WWTPAgent)myAgent).dbToxicNotification.exists(notification) == false){
							System.out.println(myAgent.getLocalName() + " NON-NOTIFIED TOXIC EFFLUENT FROM "+ sw.getOrigin().getName()+ " DETECTED!!");
						}
					}

					double litres = water.getVolume().getLitres();
					if (litres > 60){
						//mildthunderstom
						System.out.println(myAgent.getLocalName() + " MILDTHUNDERSTORM DETECTED!!");
					}
					
					if (litres + ((WWTPAgent)myAgent).usedCapacity > ((WWTPAgent)myAgent).maxCapacity){
						requestForHelp = true;
					}
					else{
						((WWTPAgent)myAgent).usedCapacity += litres;
						//direct send water
					}
					
					if (requestForHelp)
					{
						System.out.println(myAgent.getLocalName() +" REQUEST FOR HELP");
						//Request For Help
						//para saber a quien hacer bypass se necesita hacer contractnet
						RequestHelp request1 = new RequestHelp();
				        Time t = new Time();
				        t.setSeconds((int) ((WWTPAgent)myAgent).dbDirectWater.getTime(myAgent.getLocalName(),((WWTPAgent)myAgent).dbDirectWater.getMyCloserTank(myAgent.getLocalName())));
				        request1.setTimeLeft(t);
				        Origin o = new Origin();
				        o.setName(msg.getSender().getLocalName());
				        request1.setTank(o);

				        ACLMessage msg1 = new ACLMessage(ACLMessage.QUERY_REF);
						msg1.setProtocol(FIPANames.InteractionProtocol.FIPA_QUERY);
						msg1.setLanguage(((WWTPAgent)myAgent).codec.getName());
						msg1.setOntology(((WWTPAgent)myAgent).ontology.getName());
						msg1.addReceiver(new AID("Authority", AID.ISLOCALNAME));
						msg1.setConversationId("HelpRequest");

				        request1.setWaterToTreat(water);
				        request1.setTimeLeft(t);

						manager.fillContent(msg1, request1);
						myAgent.addBehaviour(new RequestForHelpBehaviour(myAgent,msg1));

					}
					else
					{
						DirectSendWater dsw = new DirectSendWater();
						dsw.setWater(water);
						actionOp = new Action(msg.getSender(), dsw);

						//Send Action
						manager.fillContent(request, actionOp);
						//System.out.println(request);
						myAgent.addBehaviour(new SimpleAchieveREInitiator(myAgent, request) {

							@Override
							protected ACLMessage prepareRequest(ACLMessage arg0) {
								// TODO Auto-generated method stub
								return super.prepareRequest(arg0);
							}

						});
					}

				}

			} catch (Exception e) {
				e.printStackTrace();
			}

		} else {
			block();
		}
	}
}
